#include "GProgressBar.h"

#include "GColor.h"
#include "Object.h"

struct _GProgressBar
{
        GWidget parent_instance;
        // 进度条的进度: 0~1
        float percent;
        /* 进度条的最大长度 */
        uint16_t bar_length;
        // 进度条框内颜色
        uint16_t bar_color;
        // 进度条框的颜色
        uint16_t frame_color;
        // 是否绘制了进度条框
        bool is_frame_drew;
};

uint16_t
g_progress_bar_get_width(const GProgressBar *self)
{
        return self->bar_length;
}

uint16_t
g_progress_bar_get_height(const GProgressBar *self)
{
        return 14;
}

void
g_progress_bar_render(GProgressBar *self,
                      uint16_t      startX,
                      uint16_t      startY,
                      uint16_t      endX,
                      uint16_t      endY)
{
        Screen *screen = screen_new_from_global();

        if (G_WIDGET(self)->is_update)
                return;
        //
        startX = g_align_scale_sx(G_WIDGET(self)->align,
                                  startX,
                                  endX,
                                  g_widget_get_min_width(G_WIDGET(self)));
        startY = g_align_scale_sy(G_WIDGET(self)->align,
                                  startY,
                                  endY,
                                  g_widget_get_min_height(G_WIDGET(self)));
        //
        startX += G_WIDGET(self)->margin;
        startY += G_WIDGET(self)->margin;

        if (!self->is_frame_drew) {
                screen_set_draw_area(screen,
                                     startX,
                                     startY,
                                     startX + self->bar_length - 1,
                                     startY + 13);
                for (short i = 0; i < 14; ++i)
                        for (uint16_t j = 0; j < self->bar_length; ++j)
                                screen_draw_pixel(screen, self->frame_color);
                self->is_frame_drew = true;
        }
        startX += 1;
        startY += 1;
        endX = startX +
               (uint16_t)(self->percent * (float)(self->bar_length - 2)) - 1;
        endY = startY + 11;
        screen_set_draw_area(screen, startX, startY, endX, endY);
        for (short i = 0; i < 12; ++i)
                for (uint16_t j = startX; j <= endX; ++j)
                        screen_draw_pixel(screen, self->bar_color);
        G_WIDGET(self)->is_update = true;
}

GWidget *
g_progress_bar_new(const uint16_t bar_length)
{
        GProgressBar *self = object_new(GProgressBar);
        g_widget_init(G_WIDGET(self),
                      G_WIDGET_NUMS_CALLBACK(g_progress_bar_get_width),
                      G_WIDGET_NUMS_CALLBACK(g_progress_bar_get_height),
                      G_WIDGET_RENDER(g_progress_bar_render));
        self->percent       = 0;
        self->bar_color     = 0x0ff0;
        self->is_frame_drew = false;
        self->bar_length    = bar_length;
        return G_WIDGET(self);
}

void
g_progress_bar_set_percent(GProgressBar *self, const float percent)
{
        if (self->percent == percent)
                return;
        self->percent = percent;
        /* 红到绿渐变色 */
        if (percent <= 0.5)
                self->bar_color = G_COLOR(255, (uint8_t)(255 * percent * 2), 0);
        else
                self->bar_color =
                        G_COLOR((uint8_t)(510 - 510 * percent), 255, 0);
        G_WIDGET(self)->is_update = false;
}

void
g_progress_bar_set_color(GProgressBar *self, const uint16_t color)
{
        if (self->bar_color == color)
                return;
        self->bar_color           = color;
        G_WIDGET(self)->is_update = false;
}

void
g_progress_bar_reset(GProgressBar *self)
{
        self->is_frame_drew       = false;
        G_WIDGET(self)->is_update = false;
}
